package pl.edu.agh.to1.dice.logic;

import java.io.IOException;
import java.util.Scanner;

public class DiceGame {

	Player[] Player;
	Bot[] Bot;
	int temp;
	int ile; // ilosc graczy
	int ileBotow;
	int licznik; // liczba tur
	int actual; // ktorego gracza jest tura
	int nLos; // liczba losowan kosci
	int variant; // czy gramy rozszerzona wersje
	Scanner odczyt = new Scanner(System.in);
	private RankingManager rankinger;

	public DiceGame(int nIle, int wariant, int ileBotow) {
		rankinger = new FileRankingManager("file.txt",new RankingEntryComparator());
		rankinger.load();
		nLos = 0;
		licznik = 0;
		actual = 0;
		ile = nIle;
		this.ileBotow = ileBotow;
		variant = wariant;
		Player = new Player[nIle];
		Bot= new Bot[ileBotow];
		for (int i = 0; i < nIle; i++) {
			System.out.println("Podaj imie gracza #"+(i+1));
			String name = odczyt.next();
			RankingEntry re = rankinger.getRankingEntry(name);
			Player[i] = new Player(variant,re);
			
		}
		for (int i = 0; i<ileBotow; i++){
			String name = "Bot #" + i;
			RankingEntry re = rankinger.getRankingEntry(name);
			Bot[i] = new Bot(variant, re);
		}
	}

	public void play() throws IOException {
		int iter = 0;
		if (variant == 0)
			iter = 1;
		else
			iter = 3;
		int turn = 13 * iter;
		for (; licznik < turn; licznik++) {
			for (int i = 0; i < ile; i++) {
				actual = i;
				tura();
			}
			for (int i = 0; i<ileBotow; i++){
				Bot[i].zagrajTure();
			}
			czyscKosci();
		}

		for (int i = 0; i < ile; i++) {
			tasujG(i);
			Player[i].score = Player[i].pTablica.valB(18);
		}
		for (int i = 0; i<ileBotow; i++){
			Bot[i].tasuj();
			Bot[i].score = Bot[i].pTablica.valB(18);
		}

		int max = 0;
		int ktory = 0;
		boolean botWon = false;
		for (int i = 0; i < ile; i++) {
			System.out.println("Gracz numer " + (i + 1) + " zdobyl punktow "
					+ Player[i].showScore());
			if (Player[i].showScore() > max) {
				max = Player[i].showScore();
				ktory = i;
			}
		}
		for ( int i=0; i<ileBotow; i++){
			System.out.println("Bot #" + i + " zdobyl punktow " + Bot[i].showScore());
			if( Bot[i].showScore() > max){
				botWon = true;
				max = Bot[i].showScore();
				ktory = i;
			}
		}
		System.out.println();
		if(botWon == false){
		System.out.println("Wygral gracz numer " + (ktory + 1) + " z " + max
				+ " punktami");
		}else{
			System.out.println("Wygral Bot #" + ktory + " z " + max + " punktami");
		}
		
		for(Player p : Player)
			p.rankingUpdate();
		for(Bot b: Bot)
			b.rankingUpdate();
		rankinger.update();
		rankinger.onClose();
	}

	void tura() {
		nLos = 0;
		temp = 0;
		while (nLos <= 1) {
			do {
				if (temp == 0) {
					tasujG(actual);
					nLos += 1;
				}
				showMenu();
				try {
					System.out.println("Blokuj kosci, 0 - by losowac");
					temp = odczyt.nextInt();
				} catch (Exception n) {
					System.out.println("Bledna dana");
					odczyt.next();
					temp = -3;
				}
				if (temp >= 1 && temp < 6) {
					Player[actual].zmien(temp - 1);
				}
			} while (temp != 0);
			tasujG(actual);
		}
		showMenu();

		boolean czyPoprawne = false;
		while (!czyPoprawne) {
			int check;
			temp = 0;
			try {
				System.out.println("Wybierz opcje");
				temp = odczyt.nextInt();
			} catch (Exception n) {
				System.out.println("bledna dana");
				odczyt.next();
			}

			if (variant == 0) {
				check = 19;
			} else {
				check = 55;
			}
			if (temp > 0 && temp <= check)
				if ((Player[actual].czyUzyte(temp - 1)))
					System.out.println("Juz uzyte");
				else
					czyPoprawne = true;
		}
		Player[actual].uzyj(temp - 1);
	}

	void showMenu() {
		System.out.println("_________________________________________");
		System.out.println("Tura: " + (licznik + 1));
		System.out.println("Aktualny gracz: " + (actual + 1));
		System.out.println("Losowanie numer: " + nLos);
		System.out.print("\n");
		if (variant == 1)
			System.out.println("Mnoznik   1x     2x       3x");
		wynikG(actual);
		System.out.print("\n");
		System.out.println("Kosci:");
		kosciG(actual);
		System.out.print("\n");

	}

	void czyscKosci() {
		for (int i = 0; i < ile; i++) {
			Player[i].czysc();
		}
	}

	void kosciG(int A) {
		Player[A].wyswKosci();
	}

	void tasujG(int A) {
		Player[A].tasuj();
	}

	void wynikG(int A) {
		Player[A].wyniki();
	}
}